home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
unix
/
utils.1
< prev
Wrap
Text File
|
1988-11-02
|
22KB
|
966 lines
Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i040: unix-utils - UNIX(tm)-like utilities
Message-ID: <10011@swan.ulowell.edu>
Date: 2 Nov 88 20:47:21 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 955
Approved: page@swan.ulowell.edu
Submitted-by: brant@uf.msc.umn.edu (Gary Brant)
Posting-number: Volume 2, Issue 40
Archive-name: unix/utils.1
Head, tail, tee and wc are similar to *NIX utilities of the same name.
detab and entab remove and instert tabs respectively in source files.
trunc removes trailing white space, inserts left margins,
deletes/converts CR's in source files, etc.
[Although the sources are copyrighted, they are freely
redistributable, as mentioned in the readme file. ..Bob]
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# detab.c
# entab.c
# head.c
# tail.c
# tee.c
# trunc.c
# wc.c
# readme
# This archive created: Wed Nov 2 15:40:18 1988
cat << \SHAR_EOF > detab.c
/* detab.c - expand tabs to spaces in a file. If a single tabstop *
* is given, tabs are tabstop spaces apart, otherwise tabstops *
* are at <tab1>, <tab2>,..., <tabn>. If no file is specified, *
* standard input is read and standard output written. *
* *
* detab [-<tab1> -<tab2>... -<tabn>] [filename... ] *
* *
* detab (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#define MAXLINE 1000
#include <stdio.h>
char tabarray[MAXLINE];
main (argc, argv) /* remove trailing blanks and tabs and */
/* expand tabs in source lines */
int argc;
char *argv[];
{
int i = 0, j, k, l, ntabs = 0, tabstop = 8;
int argtabs[99];
char ch, *pch;
FILE *ifile, *fopen ();
/* decode tabstop arguments */
while ((++i < argc) && (argv[i][0] == '-')) {
j = 1;
tabstop = 0;
while ((ch = argv[i][j++]) != '\0') {
if (ch >= '0' && ch <= '9') {
tabstop *= 10;
tabstop += ch - '0';
} else {
fputs ("bad args\n", stderr);
exit (20);
}
}
argtabs[ntabs++] = tabstop;
}
/* fill tabarray with \1 for each tabstop position */
for (k = 0; k < MAXLINE; k++)
tabarray[k] = '\0';
if (ntabs > 1)
for (k = 0; k < ntabs; k++)
if ((l = argtabs[k]-1) < MAXLINE)
tabarray[l] = '\001';
else {
fputs ("bad tab specification\n", stderr);
exit (20);
}
else if ((tabstop > 0) && (tabstop < MAXLINE))
for (k = tabstop; k < MAXLINE; k += tabstop)
tabarray[k] = '\001';
else {
fputs ("bad tab specification\n", stderr);
exit (20);
}
/* remaining arguments should be file names - detab them */
if (i < argc) {
while (i < argc)
if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
fputs ("detab: cant open ", stderr);
fputs (pch, stderr);
putc ('\n', stderr);
exit (20);
} else
detab (ifile);
} else
detab (stdin);
}
/* detab - remove the tabs from one file */
detab (ifile)
FILE *ifile;
{
int n;
char inline[MAXLINE], outline[MAXLINE], *fgets ();
while ((fgets (inline, MAXLINE, ifile)) != NULL) {
n = strlen (inline);
while (--n >= 0) /* back over white space */
if (inline[n] != ' ' && inline[n] != '\t' &&
inline[n] != '\n') break;
inline[n+1] = '\0';
expand (inline, outline, MAXLINE);
puts (outline);
}
}
/* expand - expand a line */
expand (in, out, lim)
char in[], out[];
int lim;
{
register int i, j;
register char ch;
i = j = 0;
while (((ch = in[i++]) != '\0') && (j < lim)) {
if (ch == '\t') {
register int k;
register char tc;
k = j;
out[j++] = ' ';
while ((j < lim) && ((tc = tabarray[j]) == '\0'))
out[j++] = ' ';
if (tc == '\0') {
j = k;
out[j++] = ch;
}
} else
out[j++] = ch;
}
out[j] = ch;
}
/* wb_parse is included here only to reduce the size of the executable */
void
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > entab.c
/* entab.c - compress spaces to tabs in a file. If a single tabstop *
* is given, tabs are tabstop spaces apart, otherwise tabstops *
* are at <tab1>, <tab2>,..., <tabn>. If no file is specified, *
* standard input is read and standard output written. *
* *
* entab [-<tab1> -<tab2> -<tabn>] [filename... ] *
* *
* entab (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#define MAXLINE 1000
#include <stdio.h>
char tabarray[MAXLINE];
main (argc, argv) /* remove trailing blanks and tabs and */
/* compress blanks in source lines */
int argc;
char *argv[];
{
int i = 0, j, k, l, ntabs = 0, tabstop = 8;
int argtabs[99];
char ch, *pch;
FILE *ifile, *fopen ();
/* decode tabstop arguments */
while ((++i < argc) && (argv[i][0] == '-')) {
j = 1;
tabstop = 0;
while ((ch = argv[i][j++]) != '\0') {
if (ch >= '0' && ch <= '9') {
tabstop *= 10;
tabstop += ch - '0';
} else {
fputs ("bad args\n", stderr);
exit (20);
}
}
argtabs[ntabs++] = tabstop;
}
/* fill tabarray with \1 at each tabstop position */
for (k = 0; k < MAXLINE; k++)
tabarray[k] = '\0';
if (ntabs > 1)
for (k = 0; k < ntabs; k++)
if ((l = argtabs[k]-1) < MAXLINE)
tabarray[l] = '\001';
else {
fputs ("bad tab specification\n", stderr);
exit (20);
}
else if ((tabstop > 0) && (tabstop < MAXLINE))
for (k = tabstop; k < MAXLINE; k += tabstop)
tabarray[k] = '\001';
else {
fputs ("bad tab specification\n", stderr);
exit (20);
}
/* remaining arguments should be file names - entab them */
if (i < argc)
while (i < argc)
if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
fputs ("entab: cant open ", stderr);
fputs (pch, stderr);
putc ('\n', stderr);
exit (20);
} else
entab (ifile);
else
entab (stdin);
}
/* entab - insert tabs into one file */
entab (ifile)
FILE *ifile;
{
int n;
char inline[MAXLINE], outline[MAXLINE], *fgets ();
while ((fgets (inline, MAXLINE, ifile)) != NULL) {
n = strlen (inline);
while (--n >= 0) /* back over white space */
if (inline[n] != ' ' && inline[n] != '\t' && inline[n] != '\n')
break;
inline[n+1] = '\0';
compress (inline, outline, MAXLINE);
puts (outline);
}
}
/* compress - compress one line, replacing strings of blanks with tabs *
* to tab stops specified on command line or default */
compress (in, out, lim)
char in[], out[];
int lim;
{
register int i = 0, j = 0;
register char ch;
while (((ch = in[i++]) != '\0') && (i < lim)) {
if (ch == ' ') {
register int k = i, tc;
while (((tc = tabarray[k]) == '\0') && (in[k] == ' ') && (k < lim))
k++;
if ((tc == '\001') && (k > i))
out[j++] = '\t';
else /* avoid running through this again next trip */
while (i++ <= k)
out[j++] = ch;
i = k;
} else if (ch == '\042' || ch == '\047') {
register int tc; /* avoid tabbing quoted strings */
out[j++] = ch;
while (((tc = in[i++]) != ch) && (i < lim)) {
if (tc == '\134') { /* possible protected quote */
out[j++] = tc;
tc = in[i++];
if (i == lim) break;
}
out[j++] = tc;
}
out[j++] = ch;
} else
out[j++] = ch;
}
out[j] = ch;
}
void
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > head.c
/* head.c - print the first few lines in a file. If count is specified,*
* that many lines are printed instead of the default value of *
* ten lines. If no files are specified, head reads standard *
* input. *
* *
* head [-<count>] [<file> ...] *
* *
* head (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#include <stdio.h>
#define MAXLINE 1000
void fputs ();
int head = 0;
main (argc, argv) /* list 1st n lines of a file */
int argc;
char *argv[];
{
FILE *input, *fopen ();
void fclose ();
int default_lines = 10; /* default number of lines to list */
int i = 0, j, maxlines;
char ch;
maxlines = default_lines;
while (++i < argc) {
if (argv [i][0] == '-') { /* remember to bump i in loop */
maxlines = 0; /* remember to set maxlines to 0 1st */
for (j = 1; (ch = argv[i][j]) != '\0'; j++)
if (ch >= '0' && ch <= '9') {
maxlines *= 10;
maxlines += ch - '0';
} else {
maxlines = default_lines;
break;
}
default_lines = maxlines;
} else {
++head;
if ((input = fopen (argv[i], "r")) == NULL) {
fputs ("head: can't open ", stderr);
fputs (argv[i], stderr);
putc ('\n', stderr);
break;
} else {
list (input, argv[i], maxlines);
fclose (input);
}
}
}
if (!head)
list (stdin, "", maxlines);
}
/* list head of a file */
list (fp, fn, maxlines)
FILE *fp;
char *fn;
int maxlines;
{
int n;
int i = 0;
char line[MAXLINE];
char *fgets ();
while ((i < maxlines) && (fgets (line, MAXLINE, fp)) != NULL) {
if (i++ == 0)
heading (fn);
fputs (line, stdout);
}
}
/* heading - print a short heading identifying file */
heading (filename)
char *filename;
{
if (head) {
fputs ("==> ", stdout);
fputs (filename, stdout);
fputs (" <==\n", stdout);
}
}
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > tail.c
/* tail.c - print the last few lines in a file. If count is specified, *
* that many lines are printed instead of the default value of *
* ten lines. If no files are specified, head reads standard *
* input. *
* *
* tail [-<count>] [<file> ...] *
* *
* tail (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#include <stdio.h>
#define MAXLINE 1000
void fputs ();
int default_lines = 10; /* default number of lines to list */
int head = 0;
main (argc, argv) /* list 1st n lines of a file */
int argc;
char *argv[];
{
FILE *input, *fopen ();
void fclose ();
int i = 0, j, maxlines;
char ch;
maxlines = default_lines;
while (++i < argc) {
if (argv [i][0] == '-') { /* process line count argument */
maxlines = convert (argv[i]);
default_lines = maxlines;
if (maxlines > 4096) {
fputs ("give me a break!! n <= 4096!\n", stderr);
exit (20);
}
} else if (argv [i][0] == '+') {
maxlines = -convert (argv[i]);
default_lines = maxlines;
} else {
++head;
if ((input = fopen (argv[i], "r")) == NULL) {
fputs ("tail: can't open ", stderr);
fputs (argv[i], stderr);
putc ('\n', stderr);
break;
} else {
list (input, argv[i], maxlines);
fclose (input);
}
}
}
if (!head)
list (stdin, "", maxlines);
}
list (fp, fn, maxlines) /* list tail of a file */
FILE *fp;
char *fn;
int maxlines;
{
int i = 0, n, fseek ();
char line[MAXLINE];
long cur_pos = 0L, line_pos[4096];
char *c, *fgets ();
if (maxlines < 0) { /* +n, head relative list */
while (maxlines++ < 0 && (c = fgets (line, MAXLINE, fp)) != NULL);
if (c != NULL) {
heading (fn);
while ((fgets (line, MAXLINE, fp)) != NULL)
fputs (line, stdout);
}
} else { /* -n, tail relative list */
for (n = 0; n < maxlines; n++)
line_pos[n] = 0L;
while ((fgets (line, MAXLINE, fp)) != NULL) {
n = strlen (line);
line_pos[i++] = cur_pos;
cur_pos += n;
if (i == maxlines)
i = 0;
}
if (cur_pos == 0L)
return;
fseek (fp, line_pos[i], 0);
heading (fn);
while ((fgets (line, MAXLINE, fp)) != NULL)
fputs (line, stdout);
}
}
heading (filename)
char *filename;
{
if (head) {
fputs ("==> ", stdout);
fputs (filename, stdout);
fputs (" <==\n", stdout);
}
}
convert (string)
char string[];
{
register int maxlines = 0, j;
register char ch;
for (j = 1; (ch = string[j]) != '\0'; j++)
if (ch >= '0' && ch <= '9') {
maxlines *= 10;
maxlines += ch - '0';
} else {
maxlines = default_lines;
break;
}
return (maxlines);
}
void _wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > tee.c
/* tee.c - copy standard input to standard output and one other file. *
* This is useful for splitting (tapping) the pipe. Presumes you *
* are using a shell program which can pipe the output from one *
* program into the input of another or some other pipe device, *
* but also can be used to make 2 copies of a file. *
* *
* tee <file1 >file2 file3 *
* prog1 file1 | tee file3 | prog2 ... *
* *
* tee (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#include <stdio.h>
#include <fcntl.h>
#define MAXLINE 256
#define ERROR -1
void copy ();
int close (), open (), read (), write ();
int err, out2; /* file handles */
main (argc, argv)
int argc;
char *argv[];
{
err = fileno (stderr);
if (argc != 2) {
write (err, "usage: tee <file1 >file2 file3\n", 31);
exit (20);
}
/* Manx documentation (lib.35) claims that if O_TRUNC is used, */
/* then O_CREAT is not needed; HOG_WASH; open() first deletes */
/* the file & then complains ENOENT (File does not exist!!! */
if ((out2 = open (argv[1], O_WRONLY | O_TRUNC | O_CREAT)) == ERROR) {
write (err, "tee: cant open ", 15);
write (err, argv[1], strlen (argv[1]));
write (err, "\n", 1);
exit (20);
}
copy (out2);
close (out2);
}
/* copy stdin to stdout and one other file */
void copy (out2)
int out2;
{
int p, in, out1;
char line[MAXLINE];
in = fileno (stdin);
out1 = fileno (stdout);
while ((p = read (in, line, MAXLINE)) > 0) {
write (out1, line, p);
write (out2, line, p);
}
}
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > trunc.c
/* trunc.c - Remove trailing white space from a file. In addition *
* perform some simple formatting. Options include lm (left *
* margin), lc (leftmost column to copy), rc (rightmost column *
* to copy), mc (convert CR's to LF's), and md (delete CR's). *
* *
* trunc [-<mc>|<md>][-lm n][-lc n][-rc n] [<file> ...] *
* *
* trunc (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#define MAXLINE 1000
#include <stdio.h>
int lc = 0, /* leftmost column to copy */
lm = 0, /* left margin to insert */
rc = 0; /* rightmost column to copy */
int m = 0; /* conversion flag for ^M's */
int flag = 0; /* indicates CR seen and conversion mode on */
int head = 0;
void fputs (), putc ();
main (argc, argv) /*remove trailing blanks and tabs from source lines */
int argc;
char *argv[];
{
int i = 0, j;
char ch, *pch;
FILE *ifile, *fopen ();
while ((++i < argc) && (argv[i][0] == '-')) {
j = 1;
switch (ch = argv[i][j++]) {
case 'l': if ((ch = argv[i][j]) == 'c' && i < argc - 1) {
lc = convert (argv[++i]);
if (lc > 0)
lc--;
} else if (ch = 'm' && i < argc - 1)
lm = convert (argv[++i]);
else
badarg ();
break;
case 'm': if ((ch = argv[i][j]) == 'd')
m = 1;
else if (ch == 'c')
m = 2;
break;
case 'r': if ((ch = argv[i][j]) == 'c' && i < argc - 1)
rc = convert (argv[++i]);
else
badarg ();
break;
default: badarg ();
break;
}
}
if (rc == 0) rc = MAXLINE - 1 - lm;
if (lc > rc || rc - lc + lm >= MAXLINE) badarg ();
while (i < argc) {
++head;
if ((ifile = fopen ((pch = argv[i++]), "r")) == NULL) {
fputs ("trunc: cant open ", stderr);
fputs (pch, stderr);
putc ('\n', stderr);
exit (20);
} else
copy (ifile);
}
if (head == 0)
copy (stdin);
}
/* copy - copy file, remove trailing white space and format as we go */
/* inspired by example in: K & R, P. 61 */
copy (ifile)
FILE *ifile;
{
int irc, n = 0;
char line[MAXLINE];
irc = rc + lm - lc;
while (n < lm)
line[n++] = ' ';
while ((n = getline (ifile, &line[lm], MAXLINE-1-lm)) > 0) {
register int in = (lm + n < irc) ? lm + n : irc;
while (in-- >= lm)
if (line[in] != ' ' && line[in] != '\t' && line[in] != '\n')
break;
if (in < lm) {
putc ('\n', stdout);
if (flag) {
flag = 0;
putc ('\n', stdout);
}
} else {
if (flag != 0) {
line[++in] = '\n';
flag = 0;
}
line[++in] = '\n';
line[++in] = '\0';
fputs (line, stdout);
}
}
}
/* get line into s, return length
* inspired by example in: K & R, P. 67 */
getline (ifile, s, lim)
FILE *ifile;
char s[];
int lim;
{
register int c, i, j;
i = 0; j = lc; /* leftmost columns to ignore */
while (i < lim && (c = getc (ifile)) != EOF && c != '\n') {
if (c == '\r') {
if (m == 1)
continue;
else if (m == 2) {
flag = 1;
continue;
}
}
if (j-- <= 0)
s[i++] = c;
}
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return (i);
}
/* convert - convert numeric command-line arguments to binary *
* returns -1 if non-numeric data encountered */
convert (argv)
char *argv;
{
register long i = 0;
register char ch;
register int j=0;
while ((ch = argv[j++]) != '\0')
if (ch >= '0' && ch <= '9') {
i *= 10;
i += ch - '0';
} else
return (-1);
return (i);
}
/* badarg - complain about bad argument */
badarg ()
{
fputs ("bad args\n", stderr);
exit (20);
}
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > wc.c
/* wc.c - count the number of lines, words, and characters in a file. *
* *
* wc [<file> ...] *
* *
* wc (C) 1988 by Gary L. Brant *
* *
* :ts=8 */
#include <stdio.h>
#define FALSE 0
#define TRUE 1
#define COUNT_LINES 4
#define COUNT_WORDS 2
#define COUNT_CHARS 1
int cur_flag, def_flag = COUNT_LINES | COUNT_WORDS | COUNT_CHARS;
int head;
long lines, words, chars;
long tlines=0, twords=0, tchars=0;
char string[] = " ";
main (argc, argv) /* count lines, words, chars in input */
int argc;
char *argv[];
{
register int i = 0, j;
register char ch;
FILE *input, *fopen ();
void fclose ();
cur_flag = def_flag;
while (++i < argc) {
if (argv [i][0] == '-') { /* remember to bump i in loop */
def_flag = cur_flag;
cur_flag = 0;
for (j = 1; (ch = argv[i][j]) != '\0'; j++)
switch (ch) {
case 'l':
cur_flag |= COUNT_LINES;
break;
case 'w':
cur_flag |= COUNT_WORDS;
break;
case 'c':
cur_flag |= COUNT_CHARS;
break;
default:
cur_flag = def_flag;
}
} else {
++head;
if ((input = fopen (argv[i], "r")) == NULL) {
fputs ("wc: can't open ", stderr);
fputs (argv[i], stderr);
putc ('\n', stderr);
continue;
} else {
wc (input, argv[i]);
fclose (input);
}
}
}
if (!head)
wc (stdin, "");
else if ( head > 1)
print (tlines, twords, tchars, "total");
}
/* count words, etc. in 1 file
* inspired by example from: K.&R. P. 18 */
wc (fp, fn)
FILE *fp;
char *fn;
{
register int in, c;
in = FALSE;
lines = words = chars = 0;
while ((c = getc (fp)) != EOF) {
++chars;
if (c == '\n') {
++lines;
in = FALSE;
} else if (c == ' ' || c == '\t')
in = FALSE;
else if (!in) {
in = TRUE;
++words;
}
}
print (lines, words, chars, fn);
tlines += lines;
twords += words;
tchars += chars;
}
/* print - print counts for a file */
print (lines, words, chars, fn)
long lines, words, chars;
char *fn;
{
if (cur_flag & COUNT_LINES) {
convert (lines, string);
fputs (string, stdout);
}
if (cur_flag & COUNT_WORDS) {
convert (words, string);
fputs (string, stdout);
}
if (cur_flag & COUNT_CHARS) {
convert (chars, string);
fputs (string, stdout);
}
if (head)
fputs (fn, stdout);
putc ('\n', stdout);
}
convert (val, string)
register long val;
register char *string;
{
register int i = 7;
if (val == 0)
string[i--] = '0';
while (val != 0) {
register long j, k;
j = val / 10;
k = val - 10 * j;
val = j;
string[i--] = '0' + k;
if (i < 0)
break;
}
while (i >= 0)
string[i--] = ' ';
}
_wb_parse ()
{
}
SHAR_EOF
cat << \SHAR_EOF > readme
Here are some utilities that I have found useful. head, tail, tee
and wc are similar to *NIX utilities of the same name. detab and
entab remove and instert tabs respectively in source files. trunc
removes trailing white space, inserts left margins, deletes/converts
CR's in source files, etc.
All of these utilities write to standard output and read from
standard input if a file name is not provided on the command line.
This is so that each may 'pipe' its output to the input of another.
Note that if someday *real* pipes become available (:-)), tail will
break due to seeks.
These programs were compiled using the Manx C compiler (v3.6a), but
conversion to Lattice should be easy; I have tried to keep all of
the code as straight-forward as possible.
The sources & binaries are freely distributable; you may do anything
you like with them except sell them for profit as long as you leave
my name in the source and include this notice with the source files.
Have fun.
Gary Brant
US mail: 1355 Eustis St. #1
St. Paul, MN 55108
ARPA: brant@uc.msc.umn.edu
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.